﻿using Kingdee.BOS;
using Kingdee.BOS.BusinessEntity.BillTrack;
using Kingdee.BOS.BusinessEntity.YunZhiJia;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Log;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Orm.Metadata.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using static System.Net.WebRequestMethods;


namespace LH.BOS.Business.SupplyChain.Store.PlugIn
{
    [Description("推送MES入库记录服务插件"),HotUpdate]
    public class StoreService : AbstractOperationServicePlugIn
    {
        /// <summary>
        /// 添加自定义数据校验器
        /// 在系统开始执行校验前，插件可以追加自己的校验器进入操作校验器集合
        /// </summary>
        /// <param name="e"></param>
        public override void OnAddValidators(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.AddValidatorsEventArgs e)
        {
            
            base.OnAddValidators(e);
        }



        /// <summary>
        /// 执行操作事务后事件，通知插件对象执行其它事务无关的业务逻辑（事务外触发）
        /// 1.此事件在操作执行后，操作的内部逻辑已经执行完毕；
        /// 2.此事件在操作事务提交之后；
        /// 3.此事件中的数据库处理，不受操作的事务保护
        /// 4.通常此事件，也可以做同步数据，但是此同步数据的成功与否，不需影响操作
        /// </summary>
        /// <param name="e"></param>
        public override void AfterExecuteOperationTransaction(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.AfterExecuteOperationTransaction e)
        {
            Logger.Info("BOS", "执行服务插件--------------开始");

            base.AfterExecuteOperationTransaction(e);
 
            //单据上的数据包集合
            DynamicObject[] dataEntitys = e.DataEntitys;
            //判断当前单据数据不为空
            if (dataEntitys == null || dataEntitys.Count() <= 0) return;
            //抓取当前单据操作结果集
            OperateResultCollection operateResults = this.OperationResult.OperateResult;
            if (operateResults != null && operateResults.Count() > 0 )
            {
                int successCount = 0;
                foreach (OperateResult oResult in operateResults)
                {
                    if (oResult.SuccessStatus || string.Equals("推送出库数据", oResult.Name))
                    {
                        successCount++;
                    }
                }
                if(successCount == operateResults.Count())
                {
                    //判断金蝶单据的操作结果成功后，说明此数据即可开始推送给第三方平台
                    //自行实现PushBill方法的逻辑并且记录好相关日志信息
                    PushBillList(dataEntitys);
                }
                else
                {
                    Logger.Info("BOS", "当前单据操作结果集中，没有全部成功，不能调用第三方系统！");
                }
            }
            else
            {
                Logger.Info("BOS", "操作结果为空！");
            }
            Logger.Info("BOS", "执行服务插件--------------结束");

        }
        /// <summary>
        /// 推送多个入库记录数据到MES系统
        /// </summary>
        /// <param name="dataEntitys"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void PushBillList(DynamicObject[] dataEntitys)
        {
            string formId = dataEntitys[0]["FFormId"].ToString();
            BusinessInfo businessInfo = MetaDataServiceHelper.GetFormMetaData(this.Context, formId).BusinessInfo;
            foreach (DynamicObject main in dataEntitys)
            {
                 PushBill(main, businessInfo);
            }
            
        }
        

        /// <summary>
        /// 推送入库记录数据到MES系统
        /// </summary>
        /// <param name="entity">采购入库单</param>
        /// <exception cref="NotImplementedException"></exception>
        private void PushBill(DynamicObject main, BusinessInfo businessInfo)
        {
            if (main == null)
            { return; }
            Stopwatch startNew = Stopwatch.StartNew();
            //表单编号
            var formId = main["FFormId"];
            long id = (long)main["Id"];
            var BillNo = main["BillNo"];
            DynamicObject queryMain = null;
            try
            {

                //加载单据数据
                DynamicObject[] objs = BusinessDataServiceHelper.Load(this.Context, new object[] { id }, businessInfo.GetDynamicObjectType());
                queryMain = objs[0];
                if (queryMain == null)
                {
                    throw new KDException("500", "未查询到单据：" + BillNo + "的信息！");
                }
                //判断单据的组织是不是联华（厦门）航空食品有限责任公司  2101050101，如果不是，则不需要同步MES
                JSONObject judgeOrgResult = judgeOrgInfoAsyncMes(queryMain);
                if (!judgeOrgResult.GetBool("isAsync"))
                {
                    Logger.Info("BOS", judgeOrgResult.GetString("message"));
                    return;
                }
                //判断是否要同步MES,目前只有标准采购订单的物料需要同步到MES
                JSONObject judgeResult = judgeAsyncMes(queryMain);
                if (!judgeResult.GetBool("isAsync"))
                {
                    Logger.Info("BOS", judgeResult.GetString("message"));
                    return;
                }
                Logger.Info("BOS", "可以同步MES系统");
                formId = queryMain["FFormId"];
                //批量批次创建
                pushBatchNumberToMes(queryMain);
                //入库记录数据推送
                pushStoreDataToMes(queryMain);
            }
            catch (Exception e)
            {
                Logger.Error("BOS", "推送MES入库记录失败！" + e.Message, e);
                if (queryMain == null)
                {
                    queryMain = main;
                }
                this.AddOperateResult(queryMain, false, "推送数据失败，" + e.Message);
                //保存日志
                this.saveLog(formId.ToString(), id.ToString(), BillNo.ToString(), "", "", "", false, "推送数据失败，" + e.Message);
            }
            finally
            {
                startNew.Stop();
                Logger.Info("BOS", "推送MES入库记录,耗时："+startNew.ElapsedMilliseconds+"毫秒");
            }

        }
        /// <summary>
        /// 判断单据的组织是不是联华（厦门）航空食品有限责任公司  2101050101，如果不是，则不需要同步MES
        /// </summary>
        /// <param name="queryMain"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject judgeOrgInfoAsyncMes(DynamicObject main)
        {
            JSONObject result = new JSONObject();
            result.Put("isAsync", false);
            result.Put("message", "不需要同步MES系统");
            //表单编号
            string formId = main["FFormId"].ToString();
            //单据编号
            string BillNo = main["BillNo"].ToString();
            DynamicObject stockOrgObject = null;
            if (string.Equals("STK_InStock", formId))
            {
                //采购入库单
                stockOrgObject = main["StockOrgId"] as DynamicObject;
            }
            else if (string.Equals("PUR_MRB", formId))
            {
                //采购退料单
                stockOrgObject = main["StockOrgId"] as DynamicObject;
            }
            else if (string.Equals("STK_OEMInStock", formId))
            {
                //受托加工材料入库单
                stockOrgObject = main["StockOrgId"] as DynamicObject;
            }
            else if (string.Equals("STK_OEMInStockRETURN", formId))
            {
                //受托加工材料退料单
                stockOrgObject = main["StockOrgId"] as DynamicObject;
            }
            else if (string.Equals("STK_TransferDirect", formId))
            {
                //调拨单
                stockOrgObject = main["StockOrgId"] as DynamicObject;
            }
            else
            {
                result.Put("message","表单编码："+formId+"无需同步MES！");
                return result;
            }
            if (stockOrgObject == null)
            {
                result.Put("message", "单据编号："+BillNo+"未获取到组织信息，不能同步到MES！");
                return result;
            }
            string stockOrgNumber = stockOrgObject["Number"] != null ? stockOrgObject["Number"].ToString() : "";
            if (!string.Equals("2101050101", stockOrgNumber))
            {
                result.Put("message", "单据编号：" + BillNo + "的组织是不是联华（厦门）航空食品有限责任公司，不能同步到MES！");
                return result;
            }
            result.Put("isAsync", true);
            result.Put("message", "需要同步MES系统");
            return result;
        }

        /// <summary>
        /// 判断是否要同步MES,
        /// </summary>
        /// <param name="queryMain"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject judgeAsyncMes(DynamicObject main)
        {
            JSONObject result = new JSONObject();
            result.Put("isAsync", false);
            result.Put("message", "不需要同步MES系统");
            //表单编号
            string formId = main["FFormId"].ToString();
            //单据编号
            string BillNo = main["BillNo"].ToString();
            HashSet<string> hashSet = new HashSet<string>();
            if (string.Equals("STK_InStock", formId))
            {
                //采购入库单，需要判断上游单据采购订单是否是标准采购订单
                //获取明细信息
                DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["InStockEntry"];
                if(reqEntrys != null && reqEntrys.Count() > 0)
                {
                    
                    foreach (DynamicObject item in reqEntrys)
                    {
                        //采购订单单号
                        string orderNo = item["POOrderNo"] != null ? item["POOrderNo"].ToString() : "";
                        if (!string.IsNullOrEmpty(orderNo))
                        {
                            hashSet.Add(orderNo);
                        }
                    }
                }
            }
            else if (string.Equals("PUR_MRB", formId))
            {
                //采购退料单，需要判断上游单据采购订单是否是标准采购订单
                DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["PUR_MRBENTRY"];
                if (reqEntrys != null && reqEntrys.Count() > 0)
                {
                    
                    foreach (DynamicObject item in reqEntrys)
                    {
                        //采购订单单号
                        string orderNo = item["ORDERNO"] != null ? item["ORDERNO"].ToString() : "";
                        if (!string.IsNullOrEmpty(orderNo))
                        {
                            hashSet.Add(orderNo);
                        }
                    }
                }
                
            }
            else
            {
                //其他单据，需要同步到MES系统
                result.Put("isAsync", true);
                result.Put("message", "可以同步MES系统");
                return result;
            }
            if (hashSet.Count == 0)
            {
                //说明采购入库单和采购退料单没有关联采购订单，无法判断采购订单是标准采购订单，则不能同步MES系统
                result.Put("isAsync", false);
                result.Put("message", "单据："+BillNo+"没有关联采购订单，无法判断采购订单是标准采购订单，不能同步MES系统");
                return result;
            }
            //查询采购订单信息，只要有一个采购订单是标准采购订单，则可以同步MES系统，如果没有，则不能同步MES系统
            StringBuilder sb = new StringBuilder();
            foreach (string item in hashSet)
            {
                if(sb.Length > 0)
                {
                    sb.Append(",");
                }
                sb.Append("'").Append(item).Append("'");
            }
            var sql = string.Format("select FID,FBILLNO,FBillTypeID from t_pur_poorder where FBILLNO in ( {0} ) ", sb.ToString());
            DataSet ds = DBServiceHelper.ExecuteDataSet(Context, sql);
            if (ds != null && ds.Tables != null && ds.Tables.Count > 0 && ds.Tables[0].Rows != null && ds.Tables[0].Rows.Count > 0)
            {
                DataRowCollection rows = ds.Tables[0].Rows;
                int num = 0;
                foreach (DataRow item in rows)
                {
                    string billTypeId = item["FBillTypeID"] != null ? item["FBillTypeID"].ToString() : "";
                    if (string.Equals(billTypeId, "83d822ca3e374b4ab01e5dd46a0062bd"))
                    {
                        //单据类型是 标准采购订单
                        num++;
                        break;
                    }
                }
                if (num == 0)
                {
                    result.Put("isAsync", false);
                    result.Put("message", "采购订单单据编号：" + JsonUtil.SerializeWithOutNull(hashSet) + " 的采购订单都不是标准采购订单，不能同步MES系统！");
                }
                else
                {
                    result.Put("isAsync", true);
                    result.Put("message", "采购订单单据编号：" + JsonUtil.SerializeWithOutNull(hashSet) + " 的采购订单中有标准采购订单，可以同步MES系统");
                }
            }
            else
            {
                result.Put("isAsync", false);
                result.Put("message", "未查询到采购订单信息，不能同步MES系统！采购订单单据编号："+JsonUtil.SerializeWithOutNull(hashSet));
            }

            return result;
        }



        /// <summary>
        /// 批次批量推送
        /// </summary>
        /// <param name="main">采购入库单</param>
        /// <exception cref="NotImplementedException"></exception>
        private void pushBatchNumberToMes(DynamicObject main)
        {
            Stopwatch sw = Stopwatch.StartNew();
            Logger.Info("BOS", "批量创建批次-----------开始");
            string formId = main["FFormId"].ToString();
            string id = main["Id"].ToString();
            string number = main["BillNo"].ToString();
            string apiUrl = "https://v3-ali.blacklake.cn/api/openapi/domain/web/v1/route/material/open/v1/batch_no/_bulk_save";
            string inputData = "";
            string requestResult = "";
            bool isSuccess = true;
            string error = "";
            if (string.Equals("STK_TransferDirect", formId))
            {
                //调拨单-入库
                JSONObject checkResult = checkTransferDirectData(main);
                if (!checkResult.GetBool("success"))
                {
                    //调拨单的调入仓库不是一楼车间仓、五楼车间、前处理车间仓时，无需入库
                    return;
                }
            }
            try
            {
                //组装批量批次创建的JSON数据
                string json = buildBacthNumberDataJson(main);
                inputData = json.ToString();
                //调用MES系统的批量批次创建接口，在MES系统创建批次号
                requestResult = HttpPost(apiUrl, json);
                if (string.IsNullOrEmpty(requestResult))
                {
                    isSuccess = false;
                    error = "MES系统的批量批次创建接口返回空数据！";
                }
                else
                {
                    JSONObject resultObject = JSONObject.Parse(requestResult);
                    int code = resultObject.GetInt("code");
                    if (code != 200)
                    {
                        isSuccess = false;
                        error = resultObject.GetString("message");
                    }
                }
                
            }
            catch (Exception e)
            {
                string msg = "批次批量创建失败！" + e.Message;
                Logger.Error("BOS", msg,e);
                isSuccess = false;
                error = msg;
            }
            finally
            {
                //保存日志
                this.saveLog(formId, id, number, apiUrl, inputData, requestResult, isSuccess, error);
                sw.Stop();
            }
            
            
            Logger.Info("BOS", "批量创建批次-----------结束,耗时："+sw.ElapsedMilliseconds+"毫秒");
        }
        /// <summary>
        /// 调拨单的调入仓库是一楼车间仓或者五楼车间或者前处理车间仓时，返回true, 否则返回false
        /// </summary>
        /// <param name="main"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject checkTransferDirectData(DynamicObject main)
        {
            JSONObject result = new JSONObject();
            result.Put("success", true);
            result.Put("message", "校验通过");
            var BillNo = main["BillNo"];
            //获取明细信息
            DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["TransferDirectEntry"];
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500", "表体信息为空！单据编号：" + BillNo);
            }
            int count = 0;
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                
                DynamicObject entry = reqEntrys[i];
                JSONObject check = this.checkDestStockOfTransferDirect(entry);
                if (check.GetBool("success"))
                {
                    //说明调拨单中有明细行的调拨入库仓库是1楼车间仓或者5楼车间仓或者前处理车间仓
                    count++;
                }
            }
            if (count == 0)
            {
                //说明调拨单中没有明细行的调拨入库仓库是1楼车间仓或者5楼车间仓或者前处理车间仓
                result.Put("success", false);
                result.Put("message", "单据编号："+BillNo+" 调拨单中没有明细行的调拨入库仓库是1楼车间仓或者5楼车间仓或者前处理车间仓");
            }
            return result;
        }

        /// <summary>
        /// 调拨单的调入仓库是一楼车间仓或者五楼车间或者前处理车间仓时，返回true, 否则返回false
        /// </summary>
        /// <param name="entry"></param>
        /// <returns></returns>
        private JSONObject checkDestStockOfTransferDirect(DynamicObject entry)
        {
            JSONObject result = new JSONObject();
            result.Put("success", true);
            result.Put("message", "校验通过");
            //物料
            DynamicObject materialIdObject = (DynamicObject)entry["MaterialId"];
            var materialCode = materialIdObject != null ? materialIdObject["Number"] : "";
            //调入仓库
            DynamicObject stockIdObject = (DynamicObject)entry["DestStockId"];
            //调入仓库编码
            string stockNumber = null;
            if (stockIdObject != null)
            {
                stockNumber = stockIdObject["Number"].ToString();
            }
            if (string.IsNullOrEmpty(stockNumber))
            {
                result.Put("success", false);
                result.Put("message", "物料编码：" + materialCode + "的调入仓库为空！");
            }
            if (!stockNumber.StartsWith("CK30"))
            {
                //调入仓库不是车间仓库
                result.Put("success", false);
                result.Put("message", "物料编码：" + materialCode + "的调入仓库不是车间仓库！");
            }
            return result;
        }

        /// <summary>
        /// 构建批量批次创建的JSON
        /// </summary>
        /// <param name="main">采购入库单</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private string buildBacthNumberDataJson(DynamicObject main)
        {
            
            //表单编号
            var formId = main["FFormId"];
            JSONObject resultObj = null;
            if (string.Equals("STK_InStock", formId))
            {
                //采购入库单-审核
                resultObj = buildStkInStockBatchNumberDataJson(main);
            }
            else if (string.Equals("PUR_MRB", formId))
            {
                //采购退料单-反审核
                resultObj = buildPurMrbBatchNumberDataJson(main);
            }
            else if (string.Equals("STK_OEMInStock", formId))
            {
                //受托加工材料入库单-审核
                resultObj = buildStkOemInStockBatchNumberDataJson(main);
            }
            else if (string.Equals("STK_OEMInStockRETURN", formId))
            {
                //受托加工材料退料单-反审核
                resultObj = buildStkOemInStockReturnBatchNumberDataJson(main);
            }
            else if (string.Equals("STK_TransferDirect", formId))
            {
                //调拨单-入库
                resultObj = buildStkTransferDirectBatchNumberDataJson(main);
            }
            else
            {
                throw new KDException("500", "当前单据【" +formId+"】不支持推送MES系统，请联系技术人员处理！");
            }

            string json = resultObj.ToJSONString();
            return json;
        }
        

        /// <summary>
        /// 构建采购入库单的批量批次创建的参数
        /// </summary>
        /// <param name="main">采购入库单信息</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkInStockBatchNumberDataJson(DynamicObject main)
        {
            var BillNo = main["BillNo"];
            //获取明细信息
            DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["InStockEntry"];
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500", "表体信息为空！单据编号：" + BillNo);
            }
            JSONArray ja = new JSONArray();
            JSONObject check = new JSONObject();
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                
                DynamicObject entry = reqEntrys[i];
                DynamicObject lotObj = (DynamicObject)entry["Lot"];
                var batchNo = lotObj != null ? lotObj["Number"] : "";

                DynamicObject materialIdObj = (DynamicObject)entry["MaterialId"];
                var materialCode = materialIdObj != null ? materialIdObj["Number"] : "";

                string value = check.GetString(batchNo.ToString() + "-" + materialCode.ToString());
                if(!string.IsNullOrEmpty(value))
                {
                    continue;
                }
                
                check.Put(batchNo.ToString() + "-" + materialCode.ToString(), "1");
                JSONObject obj = new JSONObject();
                //批次号
                obj.Put("batchNo", batchNo.ToString());
                //物料编号
                obj.Put("materialCode", materialCode.ToString());
                //生产日期（时间戳）
                obj.Put("produceAt", null);
                DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
                if (produceDateTime != null)
                {
                    long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                    //生产日期（时间戳）
                    obj.Put("produceAt", timestamp);

                }
                ja.Add(obj);
            }
            JSONObject resultObject = new JSONObject();
            resultObject.Put("list", ja);
            return resultObject;
        }



        /// <summary>
        /// 构建采购退料单的批量批次创建的参数
        /// </summary>
        /// <param name="reqEntrys">采购退料单信息</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildPurMrbBatchNumberDataJson(DynamicObject main)
        {
            var BillNo = main["BillNo"];
            //获取明细信息
            DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["PUR_MRBENTRY"];
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500", "表体信息为空！单据编号：" + BillNo);
            }
            JSONArray ja = new JSONArray();
            JSONObject check = new JSONObject();
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                JSONObject obj = new JSONObject();
                DynamicObject entry = reqEntrys[i];
                DynamicObject lotObj = (DynamicObject)entry["Lot"];
                var batchNo = lotObj != null ? lotObj["Number"] : "";

                DynamicObject materialIdObj = (DynamicObject)entry["MATERIALID"];
                var materialCode = materialIdObj != null ? materialIdObj["Number"] : "";
                string value = check.GetString(batchNo.ToString() + "-" + materialCode.ToString());
                if (!string.IsNullOrEmpty(value))
                {
                    continue;
                }

                check.Put(batchNo.ToString() + "-" + materialCode.ToString(), "1");
                //批次号
                obj.Put("batchNo", batchNo.ToString());
                //物料编号
                obj.Put("materialCode", materialCode.ToString());
                //生产日期（时间戳）
                obj.Put("produceAt", null);
                DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
                if (produceDateTime != null)
                {
                    long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                    //生产日期（时间戳）
                    obj.Put("produceAt", timestamp);

                }
                ja.Add(obj);
            }
            JSONObject resultObject = new JSONObject();
            resultObject.Put("list", ja);
            return resultObject;
        }
        /// <summary>
        /// 构建受托加工材料入库单的批量批次创建的参数
        /// </summary>
        /// <param name="main"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkOemInStockBatchNumberDataJson(DynamicObject main)
        {
            var BillNo = main["BillNo"];
            //获取明细信息
            DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["OEMInStockEntry"];
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500", "表体信息为空！单据编号：" + BillNo);
            }
            JSONArray ja = new JSONArray();
            JSONObject check = new JSONObject();
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                JSONObject obj = new JSONObject();
                DynamicObject entry = reqEntrys[i];
                DynamicObject lotObj = (DynamicObject)entry["Lot"];
                var batchNo = lotObj != null ? lotObj["Number"] : "";

                DynamicObject materialIdObj = (DynamicObject)entry["MaterialId"];
                var materialCode = materialIdObj != null ? materialIdObj["Number"] : "";
                string value = check.GetString(batchNo.ToString() + "-" + materialCode.ToString());
                if (!string.IsNullOrEmpty(value))
                {
                    continue;
                }

                check.Put(batchNo.ToString() + "-" + materialCode.ToString(), "1");
                //批次号
                obj.Put("batchNo", batchNo.ToString());
                //物料编号
                obj.Put("materialCode", materialCode.ToString());
                //生产日期（时间戳）
                obj.Put("produceAt", null);
                DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
                if (produceDateTime != null)
                {
                    long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                    //生产日期（时间戳）
                    obj.Put("produceAt", timestamp);

                }
                ja.Add(obj);
            }
            JSONObject resultObject = new JSONObject();
            resultObject.Put("list", ja);
            return resultObject;
        }
        /// <summary>
        /// 构建受托加工材料退料单的批量批次创建的参数
        /// </summary>
        /// <param name="main"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkOemInStockReturnBatchNumberDataJson(DynamicObject main)
        {
            var BillNo = main["BillNo"];
            //获取明细信息
            DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["OEMInStockRTNEntry"];
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500", "表体信息为空！单据编号：" + BillNo);
            }
            JSONArray ja = new JSONArray();
            JSONObject check = new JSONObject();
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                JSONObject obj = new JSONObject();
                DynamicObject entry = reqEntrys[i];
                DynamicObject lotObj = (DynamicObject)entry["Lot"];
                var batchNo = lotObj != null ? lotObj["Number"] : "";

                DynamicObject materialIdObj = (DynamicObject)entry["MaterialId"];
                var materialCode = materialIdObj != null ? materialIdObj["Number"] : "";
                string value = check.GetString(batchNo.ToString() + "-" + materialCode.ToString());
                if (!string.IsNullOrEmpty(value))
                {
                    continue;
                }

                check.Put(batchNo.ToString() + "-" + materialCode.ToString(), "1");
                //批次号
                obj.Put("batchNo", batchNo.ToString());
                //物料编号
                obj.Put("materialCode", materialCode.ToString());
                //生产日期（时间戳）
                obj.Put("produceAt", null);
                DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
                if (produceDateTime != null)
                {
                    long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                    //生产日期（时间戳）
                    obj.Put("produceAt", timestamp);

                }
                ja.Add(obj);
            }
            JSONObject resultObject = new JSONObject();
            resultObject.Put("list", ja);
            return resultObject;
        }
        /// <summary>
        /// 调拨单
        /// </summary>
        /// <param name="main"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkTransferDirectBatchNumberDataJson(DynamicObject main)
        {
            var BillNo = main["BillNo"];
            //获取明细信息
            DynamicObjectCollection reqEntrys = (DynamicObjectCollection)main["TransferDirectEntry"];
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500", "表体信息为空！单据编号：" + BillNo);
            }
            JSONArray ja = new JSONArray();
            JSONObject check = new JSONObject();
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                JSONObject obj = new JSONObject();
                DynamicObject entry = reqEntrys[i];
                DynamicObject lotObj = (DynamicObject)entry["Lot"];
                var batchNo = lotObj != null ? lotObj["Number"] : "";

                DynamicObject materialIdObj = (DynamicObject)entry["MaterialId"];
                var materialCode = materialIdObj != null ? materialIdObj["Number"] : "";
                string value = check.GetString(batchNo.ToString() + "-" + materialCode.ToString());
                
                if (!string.IsNullOrEmpty(value))
                {
                    
                    continue;
                }

                check.Put(batchNo.ToString() + "-" + materialCode.ToString(), "1");
                //批次号
                obj.Put("batchNo", batchNo.ToString());
                //物料编号
                obj.Put("materialCode", materialCode.ToString());
                //生产日期（时间戳）
                obj.Put("produceAt", null);
                DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
                if (produceDateTime != null)
                {
                    long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                    //生产日期（时间戳）
                    obj.Put("produceAt", timestamp);

                }
                ja.Add(obj);
            }
            JSONObject resultObject = new JSONObject();
            resultObject.Put("list", ja);
            return resultObject;
        }
        /// <summary>
        /// 入库记录数据推送
        /// </summary>
        /// <param name="main">采购入库单</param>
        /// <exception cref="NotImplementedException"></exception>
        private void pushStoreDataToMes(DynamicObject main)
        {
            Stopwatch sw = Stopwatch.StartNew();
            Logger.Info("BOS", "推送入库记录数据-----------开始");
            var BillNo = main["BillNo"];
            var formId = main["FFormId"];
            DynamicObjectCollection reqEntrys = null;
            if (string.Equals("STK_InStock", formId))
            {
                //采购入库单-审核
                //获取明细信息
                reqEntrys = (DynamicObjectCollection)main["InStockEntry"];
            }
            else if (string.Equals("PUR_MRB", formId))
            {
                //采购退料单-反审核
                reqEntrys = (DynamicObjectCollection)main["PUR_MRBENTRY"];
            }
            else if (string.Equals("STK_OEMInStock", formId))
            {
                //受托加工材料入库单-审核  
                reqEntrys = (DynamicObjectCollection)main["OEMInStockEntry"];
            }
            else if (string.Equals("STK_OEMInStockRETURN", formId))
            {
                //受托加工材料退料单-反审核
                reqEntrys = (DynamicObjectCollection)main["OEMInStockRTNEntry"];
            }
            else if (string.Equals("STK_TransferDirect", formId))
            {
                //调拨单-入库
                reqEntrys = (DynamicObjectCollection)main["TransferDirectEntry"];
            }
            else
            {
                throw new KDException("500", "当前单据【" + formId + "】不支持推送MES系统，请联系技术人员处理！");
            }
           
            if (reqEntrys == null || reqEntrys.Count() == 0)
            {
                throw new KDException("500","表体信息为空！单据编号：" + BillNo);
            }
            string apiUrl = "https://v3-ali.blacklake.cn/api/openapi/domain/web/v1/route/inventory/open/v2/inbound_order/execute/_inbound";
            //采购入库单数据推送到MES系统是按明细行推送的，一条采购入库单的明细数据对应MES系统的一条入库记录数据
            for (int i = 0; i < reqEntrys.Count(); i++)
            {
                DynamicObject entry = reqEntrys[i];
                if (string.Equals("STK_TransferDirect", formId))
                {
                    //调拨单出库
                    JSONObject judgeResult = this.checkDestStockOfTransferDirect(entry);
                    if (!judgeResult.GetBool("success"))
                    {
                        //调拨单的调入仓库不是一楼车间仓、五楼车间仓、前处理车间仓时，无需出库
                        continue;
                    }
                }

                string seq = entry["Seq"].ToString();
                string id = entry["Id"].ToString();
                string inputData = "";
                string requestResult = "";
                bool isSuccess = true;
                string error = "";
                try
                {
                    //组装入库的JSON数据
                    string json = buildStoreDataJson(main, entry);
                    inputData = json.ToString();
                    //调用MES系统的普通入库无id接口，在MES系统新增入库记录
                    requestResult = HttpPost(apiUrl, json);
                    if (string.IsNullOrEmpty(requestResult))
                    {
                        throw new KDException("500", "MES系统的普通入库无id接口返回空数据！");
                    }
                    JSONObject resultObject = JSONObject.Parse(requestResult);
                    int code = resultObject.GetInt("code");
                    if (code != 200)
                    {
                        throw new KDException("500", resultObject.GetString("message"));
                    }
                    string msg = string.Format("单据：{0}明细信息中第{1}行物料推送MES系统的入库记录成功！", BillNo, seq);
                    this.AddOperateResult(entry, true, msg);
                }
                catch (Exception e)
                {
                    string msg = string.Format("单据：{0}明细信息中第{1}行物料推送MES系统的入库记录失败！{2}",BillNo,seq,e.Message);
                    Logger.Error("BOS",msg,e);
                    isSuccess = false;
                    error = msg;
                    this.AddOperateResult(entry, false, msg);
                }
                finally
                {
                    //保存日志
                    this.saveLog(formId.ToString(), id, BillNo.ToString(), apiUrl, inputData, requestResult, isSuccess, error);
                }
            }
            sw.Stop();
            Logger.Info("BOS", "推送入库记录数据-----------结束,耗时："+sw.ElapsedMilliseconds+"毫秒");

        }
        /// <summary>
        /// 构建入库数据JSON
        /// </summary>
        /// <param name="entry">采购入库单明细行数据</param>
        /// <exception cref="NotImplementedException"></exception>
        private string buildStoreDataJson(DynamicObject main,DynamicObject entry)
        {
            //表单编号
            var formId = main["FFormId"];
            JSONObject resultObj = null;
            if (string.Equals("STK_InStock", formId))
            {
                //采购入库单-审核
                resultObj = buildStkInStockStoreDataJson(main, entry);
            }
            else if (string.Equals("PUR_MRB", formId))
            {
                //采购退料单-反审核
                resultObj = buildPurMrbStoreDataJson(main, entry);
            }
            else if (string.Equals("STK_OEMInStock", formId))
            {
                //受托加工材料入库单-审核
                resultObj = buildStkOemInStockStoreDataJson(main, entry);
            }
            else if (string.Equals("STK_OEMInStockRETURN", formId))
            {
                //受托加工材料退料单-反审核
                resultObj = buildStkOemInStockReturnStoreDataJson(main, entry);
            }
            else if (string.Equals("STK_TransferDirect", formId))
            {
                //调拨单-入库
                resultObj = buildStkTransferDirectStoreDataJson(main, entry);
            }
            else
            {
                throw new KDException("500", "当前单据【" + formId + "】不支持推送MES系统，请联系技术人员处理！");
            }
            return resultObj.ToJSONString();
        }
        

        /// <summary>
        /// 采购入库单的新增入库记录的参数
        /// </summary>
        /// <param name="main">采购入库单信息</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkInStockStoreDataJson(DynamicObject main, DynamicObject entry)
        {
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            DynamicObject stockIdObject = (DynamicObject)entry["StockId"];
            //仓库编号
            var stockNumber = stockIdObject != null ? stockIdObject["Number"] : "";
            //备注
            string remark = entry["Note"] != null ? entry["Note"].ToString() : "";
            //标识码 = 单据编号+明细信息行号
            //单据编号
            string billNo = main["BillNo"].ToString();
            //明细信息行号
            string seq = entry["Seq"].ToString();
            remark = remark + " 单据编号：" + billNo + "，明细信息行号：" + seq;
            remark = remark.Trim();

            //入库库存明细属性
            JSONObject inventoryAttrObj = new JSONObject();

            //批号
            DynamicObject lotObject = (DynamicObject)entry["Lot"];
            var batchNo = lotObject != null ? lotObject["Number"] : "";
            inventoryAttrObj.Put("batchNo", batchNo.ToString());

            //物料编号
            DynamicObject materialIdObject = (DynamicObject)entry["MaterialId"];
            var materialCode = materialIdObject != null ? materialIdObject["Number"] : "";
            inventoryAttrObj.Put("materialCode", materialCode.ToString());
            //生产日期（时间戳）
            DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
            if (produceDateTime != null)
            {
                long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("productTime", timestamp);

            }
            //位置编号
            //仓位编码
            string stockLocCodeStr = null;
            DynamicObject stockLocIdObject = (DynamicObject)entry["StockLocId"];
            if (stockLocIdObject != null) {
                DynamicObject f100002Obj = (DynamicObject)stockLocIdObject["F100002"];
                var stockLocCode = f100002Obj != null ? f100002Obj["Number"] : "";
                stockLocCodeStr = stockLocCode.ToString();
            }
            if (string.IsNullOrEmpty(stockLocCodeStr))
            {
                //当ERP没有仓位时，传仓库编码
                stockLocCodeStr = stockNumber.ToString();
            }
            inventoryAttrObj.Put("storageLocationCode", stockLocCodeStr);
            //供应商编号
            DynamicObject supplierIdObject = (DynamicObject)main["SupplierId"];
            var supplierCode = supplierIdObject != null ? supplierIdObject["Number"] : "";
            inventoryAttrObj.Put("supplierCode", supplierCode.ToString());
            //有效期至（时间戳）
            DateTime expiryDateTime = Convert.ToDateTime(entry["ExpiryDate"]);
            if (expiryDateTime != null)
            {
                long timestamp = (long)(expiryDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("validityPeriod", timestamp);

            }
            //物料信息
            JSONArray codeList = new JSONArray();
            JSONObject codeObj = new JSONObject();
            codeList.Add(codeObj);
            codeObj.Put("codeCount", 1);
            //执行数量
            JSONObject amountObj = new JSONObject();
            codeObj.Put("amount", amountObj);
            //数量
            string realQtyStr = entry["RealQty"] != null ? entry["RealQty"].ToString() : "0";
            if (double.TryParse(realQtyStr, out double result))
            {
                amountObj.Put("amount", result);
            }
            else
            {
                amountObj.Put("amount", 0);
            }
            //单位名称
            DynamicObject unitIDObject = (DynamicObject)entry["UnitID"];
            var name = unitIDObject["Name"];
            JSONArray nameJa = JSONArray.Parse(JsonUtil.SerializeWithOutNull(name));

            if (nameJa != null && nameJa.Count() > 0)
            {
                Object unitNameObject = nameJa.ElementAt<Object>(0);
                JSONObject nameobj = JSONObject.Parse(JsonUtil.SerializeWithOutNull(unitNameObject));
                string unitName = nameobj.GetString("Value");
                amountObj.Put("unitName", ConvertUnitName(unitName));
            }
            else
            {
                amountObj.Put("unitName", "");
            }

            JSONObject inboundOrderCustomField = new JSONObject();
            JSONArray customFields = new JSONArray();
            inboundOrderCustomField.Put("customFields", customFields);
            JSONObject customField = new JSONObject();
            customFields.Add(customField);
            customField.Put("fieldCode", "cust_field16__c");
            customField.Put("fieldValue", "采购入库单");

            JSONObject recordCustomField = new JSONObject();
            JSONArray customFields2 = new JSONArray();
            recordCustomField.Put("customFields", customFields2);
            JSONObject orderNoField = new JSONObject();
            customFields2.Add(orderNoField);
            orderNoField.Put("fieldCode", "cust_field11__c");
            //采购订单号
            string orderNo = entry["POOrderNo"] != null ? entry["POOrderNo"].ToString() : "";
            orderNoField.Put("fieldValue", orderNo);

            JSONObject resultObj = new JSONObject();
            //入库类型
            resultObj.Put("bizType", "0");
            //入库单号
            resultObj.Put("inboundOrderCode", null);
            //仓库编号
            resultObj.Put("wareHouseCode", stockNumber.ToString());
            //规格入库 执行数据
            resultObj.Put("codeCountList", codeList);
            //入库库存明细属性
            resultObj.Put("inventoryAttr", inventoryAttrObj);
            //备注
            resultObj.Put("remark", remark);
            //入库单自定义字段
            resultObj.Put("inboundOrderCustomField", inboundOrderCustomField);
            //入库记录自定义字段
            resultObj.Put("recordCustomField", recordCustomField);

            return resultObj;
        }

        /// <summary>
        /// 采购退料单的新增入库记录的参数
        /// </summary>
        /// <param name="main">采购退料单信息</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildPurMrbStoreDataJson(DynamicObject main, DynamicObject entry)
        {
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            DynamicObject stockIdObject = (DynamicObject)entry["STOCKID"];
            //仓库编号
            var stockNumber = stockIdObject != null ? stockIdObject["Number"] : "";
            //备注
            string remark = entry["NOTE"] != null ? entry["NOTE"].ToString() : "";
            //标识码 = 单据编号+明细信息行号
            //单据编号
            string billNo = main["BillNo"].ToString();
            //明细信息行号
            string seq = entry["Seq"].ToString();
            remark = remark + " 单据编号：" + billNo + "，明细信息行号：" + seq;
            remark = remark.Trim();

            //入库库存明细属性
            JSONObject inventoryAttrObj = new JSONObject();

            //批号
            DynamicObject lotObject = (DynamicObject)entry["Lot"];
            var batchNo = lotObject != null ? lotObject["Number"] : "";
            inventoryAttrObj.Put("batchNo", batchNo.ToString());

            //物料编号
            DynamicObject materialIdObject = (DynamicObject)entry["MATERIALID"];
            var materialCode = materialIdObject != null ? materialIdObject["Number"] : "";
            inventoryAttrObj.Put("materialCode", materialCode.ToString());
            //生产日期（时间戳）
            DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
            if (produceDateTime != null)
            {
                long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("productTime", timestamp);

            }
            //位置编号
            //仓位编码
            string stockLocCodeStr = null;
            DynamicObject stockLocIdObject = (DynamicObject)entry["FSTOCKLOCID"];
            if (stockLocIdObject != null)
            {
                DynamicObject f100002Obj = (DynamicObject)stockLocIdObject["F100002"];
                var stockLocCode = f100002Obj != null ? f100002Obj["Number"] : "";
                stockLocCodeStr = stockLocCode.ToString();
            }
            if (string.IsNullOrEmpty(stockLocCodeStr))
            {
                //当ERP没有仓位时，传仓库编码
                stockLocCodeStr = stockNumber.ToString();
            }

            inventoryAttrObj.Put("storageLocationCode", stockLocCodeStr);
            //供应商编号
            DynamicObject supplierIdObject = (DynamicObject)main["SUPPLIERID"];
            var supplierCode = supplierIdObject != null ? supplierIdObject["Number"] : "";
            inventoryAttrObj.Put("supplierCode", supplierCode.ToString());
            //有效期至（时间戳）
            DateTime expiryDateTime = Convert.ToDateTime(entry["EXPIRYDATE"]);
            if (expiryDateTime != null)
            {
                long timestamp = (long)(expiryDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("validityPeriod", timestamp);

            }
            //物料信息
            JSONArray codeList = new JSONArray();
            JSONObject codeObj = new JSONObject();
            codeList.Add(codeObj);
            codeObj.Put("codeCount", 1);
            //执行数量
            JSONObject amountObj = new JSONObject();
            codeObj.Put("amount", amountObj);
            //数量
            string realQtyStr = entry["RMREALQTY"] != null ? entry["RMREALQTY"].ToString() : "0";
            if (double.TryParse(realQtyStr, out double result))
            {
                amountObj.Put("amount", result);
            }
            else
            {
                amountObj.Put("amount", 0);
            }
            //单位名称
            amountObj.Put("unitName", "");
            DynamicObjectCollection materialStockList = (DynamicObjectCollection)materialIdObject["MaterialStock"];
            if (materialStockList != null && materialStockList.Count() > 0)
            {
                DynamicObject materialStockObject = (DynamicObject)materialStockList[0];
                if (materialStockObject != null)
                {
                    DynamicObject storeUnitObject = (DynamicObject)materialStockObject["StoreUnitID"];
                    if (storeUnitObject != null)
                    {
                        var name = storeUnitObject["Name"];
                        JSONArray nameJa = JSONArray.Parse(JsonUtil.SerializeWithOutNull(name));

                        if (nameJa != null && nameJa.Count() > 0)
                        {
                            Object unitNameObject = nameJa.ElementAt<Object>(0);
                            JSONObject nameobj = JSONObject.Parse(JsonUtil.SerializeWithOutNull(unitNameObject));
                            string unitName = nameobj.GetString("Value");
                            amountObj.Put("unitName", ConvertUnitName(unitName));
                        }
                    }
                }
            }


            JSONObject inboundOrderCustomField = new JSONObject();
            JSONArray customFields = new JSONArray();
            inboundOrderCustomField.Put("customFields", customFields);
            JSONObject customField = new JSONObject();
            customFields.Add(customField);
            customField.Put("fieldCode", "cust_field16__c");
            customField.Put("fieldValue", "采购退库单反审核");


            JSONObject recordCustomField = new JSONObject();
            JSONArray customFields2 = new JSONArray();
            recordCustomField.Put("customFields", customFields2);
            JSONObject orderNoField = new JSONObject();
            customFields2.Add(orderNoField);
            orderNoField.Put("fieldCode", "cust_field11__c");
            //采购订单号
            string orderNo = entry["ORDERNO"] != null ? entry["ORDERNO"].ToString() : "";
            orderNoField.Put("fieldValue", orderNo);

            JSONObject resultObj = new JSONObject();
            //入库类型
            resultObj.Put("bizType", "0");
            //入库单号
            resultObj.Put("inboundOrderCode", null);
            //仓库编号
            resultObj.Put("wareHouseCode", stockNumber.ToString());
            //规格入库 执行数据
            resultObj.Put("codeCountList", codeList);
            //入库库存明细属性
            resultObj.Put("inventoryAttr", inventoryAttrObj);
            //备注
            resultObj.Put("remark", remark);
            //入库单自定义字段
            resultObj.Put("inboundOrderCustomField", inboundOrderCustomField);
            //入库记录自定义字段
            resultObj.Put("recordCustomField", recordCustomField);
            return resultObj;
        }
        /// <summary>
        /// 受托加工材料入库单的新增入库记录的参数
        /// </summary>
        /// <param name="main"></param>
        /// <param name="entry"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkOemInStockStoreDataJson(DynamicObject main, DynamicObject entry)
        {
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            //仓库编号
            DynamicObject stockIdObject = (DynamicObject)entry["StockId"];
            var stockNumber = stockIdObject != null ? stockIdObject["Number"] : "";
            //备注
            string remark = entry["Note"] != null ? entry["Note"].ToString() : "";
            //标识码 = 单据编号+明细信息行号
            //单据编号
            string billNo = main["BillNo"].ToString();
            //明细信息行号
            string seq = entry["Seq"].ToString();
            remark = remark + " 单据编号：" + billNo + "，明细信息行号：" + seq;
            remark = remark.Trim();

            //入库库存明细属性
            JSONObject inventoryAttrObj = new JSONObject();

            //批号
            DynamicObject lotObject = (DynamicObject)entry["Lot"];
            var batchNo = lotObject != null ? lotObject["Number"] : "";
            inventoryAttrObj.Put("batchNo", batchNo.ToString());

            //物料编号
            DynamicObject materialIdObject = (DynamicObject)entry["MaterialId"];
            var materialCode = materialIdObject != null ? materialIdObject["Number"] : "";
            inventoryAttrObj.Put("materialCode", materialCode.ToString());
            //生产日期（时间戳）
            DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
            if (produceDateTime != null)
            {
                long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("productTime", timestamp);

            }
            //位置编号
            //仓位编码
            string stockLocCodeStr = null;
            DynamicObject stockLocIdObject = (DynamicObject)entry["StockLocId"];
            if (stockLocIdObject != null)
            {
                DynamicObject f100002Obj = (DynamicObject)stockLocIdObject["F100002"];
                var stockLocCode = f100002Obj != null ? f100002Obj["Number"] : "";
                stockLocCodeStr = stockLocCode.ToString();
            }
            if (string.IsNullOrEmpty(stockLocCodeStr))
            {
                //当ERP没有仓位时，传仓库编码
                stockLocCodeStr = stockNumber.ToString();
            }
            inventoryAttrObj.Put("storageLocationCode", stockLocCodeStr);
            //客户编号
            //DynamicObject supplierIdObject = (DynamicObject)main["CustId"];
            //var supplierCode = supplierIdObject != null ? supplierIdObject["Number"] : "";
            //inventoryAttrObj.Put("supplierCode", supplierCode.ToString());
            //有效期至（时间戳）
            DateTime expiryDateTime = Convert.ToDateTime(entry["ExpiryDate"]);
            if (expiryDateTime != null)
            {
                long timestamp = (long)(expiryDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("validityPeriod", timestamp);

            }
            //物料信息
            JSONArray codeList = new JSONArray();
            JSONObject codeObj = new JSONObject();
            codeList.Add(codeObj);
            codeObj.Put("codeCount", 1);
            //执行数量
            JSONObject amountObj = new JSONObject();
            codeObj.Put("amount", amountObj);
            //数量
            string realQtyStr = entry["Qty"] != null ? entry["Qty"].ToString() : "0";
            if (double.TryParse(realQtyStr, out double result))
            {
                amountObj.Put("amount", result);
            }
            else
            {
                amountObj.Put("amount", 0);
            }
            //单位名称
            DynamicObject unitIDObject = (DynamicObject)entry["UnitID"];
            var name = unitIDObject["Name"];
            JSONArray nameJa = JSONArray.Parse(JsonUtil.SerializeWithOutNull(name));

            if (nameJa != null && nameJa.Count() > 0)
            {
                Object unitNameObject = nameJa.ElementAt<Object>(0);
                JSONObject nameobj = JSONObject.Parse(JsonUtil.SerializeWithOutNull(unitNameObject));
                string unitName = nameobj.GetString("Value");
                amountObj.Put("unitName", ConvertUnitName(unitName));
            }
            else
            {
                amountObj.Put("unitName", "");
            }

            JSONObject inboundOrderCustomField = new JSONObject();
            JSONArray customFields = new JSONArray();
            inboundOrderCustomField.Put("customFields", customFields);
            JSONObject customField = new JSONObject();
            customFields.Add(customField);
            customField.Put("fieldCode", "cust_field16__c");
            customField.Put("fieldValue", "受托入库单");


            JSONObject recordCustomField = new JSONObject();
            JSONArray customFields2 = new JSONArray();
            recordCustomField.Put("customFields", customFields2);
            JSONObject orderNoField = new JSONObject();
            customFields2.Add(orderNoField);
            orderNoField.Put("fieldCode", "cust_field11__c");
            orderNoField.Put("fieldValue", billNo);

            JSONObject resultObj = new JSONObject();
            //入库类型
            resultObj.Put("bizType", "0");
            //入库单号
            resultObj.Put("inboundOrderCode", null);
            //仓库编号
            resultObj.Put("wareHouseCode", stockNumber.ToString());
            //规格入库 执行数据
            resultObj.Put("codeCountList", codeList);
            //入库库存明细属性
            resultObj.Put("inventoryAttr", inventoryAttrObj);
            //备注
            resultObj.Put("remark", remark);
            //入库单自定义字段
            resultObj.Put("inboundOrderCustomField", inboundOrderCustomField);
            //入库记录自定义字段
            resultObj.Put("recordCustomField", recordCustomField);
            return resultObj;
        }
        /// <summary>
        /// 受托加工材料退料单的新增入库记录的参数
        /// </summary>
        /// <param name="main"></param>
        /// <param name="entry"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkOemInStockReturnStoreDataJson(DynamicObject main, DynamicObject entry)
        {
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            //仓库编号
            DynamicObject stockIdObject = (DynamicObject)entry["StockId"];
            var stockNumber = stockIdObject != null ? stockIdObject["Number"] : "";
            //备注
            string remark = entry["Note"] != null ? entry["Note"].ToString() : "";
            //标识码 = 单据编号+明细信息行号
            //单据编号
            string billNo = main["BillNo"].ToString();
            //明细信息行号
            string seq = entry["Seq"].ToString();
            remark = remark + " 单据编号：" + billNo+"，明细信息行号："+seq;
            remark = remark.Trim();

            //入库库存明细属性
            JSONObject inventoryAttrObj = new JSONObject();

            //批号
            DynamicObject lotObject = (DynamicObject)entry["Lot"];
            var batchNo = lotObject != null ? lotObject["Number"] : "";
            inventoryAttrObj.Put("batchNo", batchNo.ToString());

            //物料编号
            DynamicObject materialIdObject = (DynamicObject)entry["MaterialId"];
            var materialCode = materialIdObject != null ? materialIdObject["Number"] : "";
            inventoryAttrObj.Put("materialCode", materialCode.ToString());
            //生产日期（时间戳）
            DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
            if (produceDateTime != null)
            {
                long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("productTime", timestamp);

            }
            //位置编号
            //仓位编码
            string stockLocCodeStr = null;
            DynamicObject stockLocIdObject = (DynamicObject)entry["StockLocId"];
            if (stockLocIdObject != null)
            {
                DynamicObject f100002Obj = (DynamicObject)stockLocIdObject["F100002"];
                var stockLocCode = f100002Obj != null ? f100002Obj["Number"] : "";
                stockLocCodeStr = stockLocCode.ToString();
            }
            if (string.IsNullOrEmpty(stockLocCodeStr))
            {
                //当ERP没有仓位时，传仓库编码
                stockLocCodeStr = stockNumber.ToString();
            }
            inventoryAttrObj.Put("storageLocationCode", stockLocCodeStr);
            //客户编号
            //DynamicObject supplierIdObject = (DynamicObject)main["CustId"];
            //var supplierCode = supplierIdObject != null ? supplierIdObject["Number"] : "";
            //inventoryAttrObj.Put("supplierCode", supplierCode.ToString());
            //有效期至（时间戳）
            DateTime expiryDateTime = Convert.ToDateTime(entry["ExpiryDate"]);
            if (expiryDateTime != null)
            {
                long timestamp = (long)(expiryDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("validityPeriod", timestamp);

            }
            //物料信息
            JSONArray codeList = new JSONArray();
            JSONObject codeObj = new JSONObject();
            codeList.Add(codeObj);
            codeObj.Put("codeCount", 1);
            //执行数量
            JSONObject amountObj = new JSONObject();
            codeObj.Put("amount", amountObj);
            //数量
            string realQtyStr = entry["Qty"] != null ? entry["Qty"].ToString() : "0";
            if (double.TryParse(realQtyStr, out double result))
            {
                amountObj.Put("amount", result);
            }
            else
            {
                amountObj.Put("amount", 0);
            }
            //单位名称
            DynamicObject unitIDObject = (DynamicObject)entry["UnitID"];
            var name = unitIDObject["Name"];
            JSONArray nameJa = JSONArray.Parse(JsonUtil.SerializeWithOutNull(name));

            if (nameJa != null && nameJa.Count() > 0)
            {
                Object unitNameObject = nameJa.ElementAt<Object>(0);
                JSONObject nameobj = JSONObject.Parse(JsonUtil.SerializeWithOutNull(unitNameObject));
                string unitName = nameobj.GetString("Value");
                amountObj.Put("unitName", ConvertUnitName(unitName));
            }
            else
            {
                amountObj.Put("unitName", "");
            }

            JSONObject inboundOrderCustomField = new JSONObject();
            JSONArray customFields = new JSONArray();
            inboundOrderCustomField.Put("customFields", customFields);
            JSONObject customField = new JSONObject();
            customFields.Add(customField);
            customField.Put("fieldCode", "cust_field16__c");
            customField.Put("fieldValue", "受托退库单反审核");


            JSONObject recordCustomField = new JSONObject();
            JSONArray customFields2 = new JSONArray();
            recordCustomField.Put("customFields", customFields2);
            JSONObject orderNoField = new JSONObject();
            customFields2.Add(orderNoField);
            orderNoField.Put("fieldCode", "cust_field11__c");
            orderNoField.Put("fieldValue", billNo);

            JSONObject resultObj = new JSONObject();
            //入库类型
            resultObj.Put("bizType", "0");
            //入库单号
            resultObj.Put("inboundOrderCode", null);
            //仓库编号
            resultObj.Put("wareHouseCode", stockNumber.ToString());
            //规格入库 执行数据
            resultObj.Put("codeCountList", codeList);
            //入库库存明细属性
            resultObj.Put("inventoryAttr", inventoryAttrObj);
            //备注
            resultObj.Put("remark", remark);
            //入库单自定义字段
            resultObj.Put("inboundOrderCustomField", inboundOrderCustomField);
            //入库记录自定义字段
            resultObj.Put("recordCustomField", recordCustomField);
            return resultObj;
        }
        /// <summary>
        /// 调拨单的新增入库记录的参数
        /// </summary>
        /// <param name="main"></param>
        /// <param name="entry"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private JSONObject buildStkTransferDirectStoreDataJson(DynamicObject main, DynamicObject entry)
        {
            // 计算自1970年1月1日00:00:00 UTC以来的毫秒数
            DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            string fieldValue = "调拨入库单";
            //调入仓位编码
            string stockLocCodeStr = null;
            string operation = this.FormOperation.Operation;
            DynamicObject stockIdObject = null;
            string stockNumber = null;
            if (string.Equals("Audit", operation))
            {
                //调拨单审核
                //调入仓库编号
                stockIdObject = (DynamicObject)entry["DestStockId"];
                stockNumber = stockIdObject != null ? stockIdObject["Number"].ToString() : "";
                DynamicObject stockLocIdObject = (DynamicObject)entry["DestStockLocId"];
                if (stockLocIdObject != null)
                {
                    DynamicObject f100002Obj = (DynamicObject)stockLocIdObject["F100002"];
                    var stockLocCode = f100002Obj != null ? f100002Obj["Number"] : "";
                    stockLocCodeStr = stockLocCode.ToString();
                }
                fieldValue = "调拨入库单";

            }
            else if (string.Equals("UnAudit", operation))
            {
                //调拨单反审核
                //调出仓库编号
                stockIdObject = (DynamicObject)entry["SrcStockId"];
                stockNumber = stockIdObject != null ? stockIdObject["Number"].ToString() : "";
                DynamicObject stockLocIdObject = (DynamicObject)entry["SrcStockLocId"];
                if (stockLocIdObject != null)
                {
                    DynamicObject f100002Obj = (DynamicObject)stockLocIdObject["F100002"];
                    var stockLocCode = f100002Obj != null ? f100002Obj["Number"] : "";
                    stockLocCodeStr = stockLocCode.ToString();
                }
                fieldValue = "调拨入库单反审核";

            }
            if (string.IsNullOrEmpty(stockLocCodeStr))
            {
                //当ERP没有仓位时，传仓库编码
                stockLocCodeStr = stockNumber.ToString();
            }



            //备注
            string remark = entry["NoteEntry"] != null ? entry["NoteEntry"].ToString() : "";
            //标识码 = 单据编号+明细信息行号
            //单据编号
            string billNo = main["BillNo"].ToString();
            //明细信息行号
            string seq = entry["Seq"].ToString();
            remark = remark + " 单据编号：" + billNo + "，明细信息行号：" + seq;
            remark = remark.Trim();

            //入库库存明细属性
            JSONObject inventoryAttrObj = new JSONObject();
            inventoryAttrObj.Put("storageLocationCode", stockLocCodeStr);

            //批号
            DynamicObject lotObject = (DynamicObject)entry["Lot"];
            var batchNo = lotObject != null ? lotObject["Number"] : "";
            inventoryAttrObj.Put("batchNo", batchNo.ToString());

            //物料编号
            DynamicObject materialIdObject = (DynamicObject)entry["MaterialId"];
            var materialCode = materialIdObject != null ? materialIdObject["Number"] : "";
            inventoryAttrObj.Put("materialCode", materialCode.ToString());
            //生产日期（时间戳）
            DateTime produceDateTime = Convert.ToDateTime(entry["ProduceDate"]);
            if (produceDateTime != null)
            {
                long timestamp = (long)(produceDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("productTime", timestamp);

            }
            
            //客户编号
            //DynamicObject supplierIdObject = (DynamicObject)main["CustId"];
            //var supplierCode = supplierIdObject != null ? supplierIdObject["Number"] : "";
            //inventoryAttrObj.Put("supplierCode", supplierCode.ToString());
            //有效期至（时间戳）
            DateTime expiryDateTime = Convert.ToDateTime(entry["ExpiryDate"]);
            if (expiryDateTime != null)
            {
                long timestamp = (long)(expiryDateTime.ToUniversalTime() - epoch).TotalMilliseconds;
                inventoryAttrObj.Put("validityPeriod", timestamp);

            }
            //物料信息
            JSONArray codeList = new JSONArray();
            JSONObject codeObj = new JSONObject();
            codeList.Add(codeObj);
            codeObj.Put("codeCount", 1);
            //执行数量
            JSONObject amountObj = new JSONObject();
            codeObj.Put("amount", amountObj);
            //数量
            string realQtyStr = entry["Qty"] != null ? entry["Qty"].ToString() : "0";
            if (double.TryParse(realQtyStr, out double result))
            {
                amountObj.Put("amount", result);
            }
            else
            {
                amountObj.Put("amount", 0);
            }
            //单位名称
            DynamicObject unitIDObject = (DynamicObject)entry["UnitID"];
            var name = unitIDObject["Name"];
            JSONArray nameJa = JSONArray.Parse(JsonUtil.SerializeWithOutNull(name));

            if (nameJa != null && nameJa.Count() > 0)
            {
                Object unitNameObject = nameJa.ElementAt<Object>(0);
                JSONObject nameobj = JSONObject.Parse(JsonUtil.SerializeWithOutNull(unitNameObject));
                string unitName = nameobj.GetString("Value");
                amountObj.Put("unitName", ConvertUnitName(unitName));
            }
            else
            {
                amountObj.Put("unitName", "");
            }

            JSONObject inboundOrderCustomField = new JSONObject();
            JSONArray customFields = new JSONArray();
            inboundOrderCustomField.Put("customFields", customFields);
            JSONObject customField = new JSONObject();
            customFields.Add(customField);
            customField.Put("fieldCode", "cust_field16__c");
            customField.Put("fieldValue", fieldValue);


            JSONObject recordCustomField = new JSONObject();
            JSONArray customFields2 = new JSONArray();
            recordCustomField.Put("customFields", customFields2);
            JSONObject orderNoField = new JSONObject();
            customFields2.Add(orderNoField);
            orderNoField.Put("fieldCode", "cust_field11__c");
            orderNoField.Put("fieldValue", billNo);

            JSONObject resultObj = new JSONObject();
            //入库类型
            resultObj.Put("bizType", "0");
            //入库单号
            resultObj.Put("inboundOrderCode", null);
            //仓库编号
            resultObj.Put("wareHouseCode", stockNumber);
            //规格入库 执行数据
            resultObj.Put("codeCountList", codeList);
            //入库库存明细属性
            resultObj.Put("inventoryAttr", inventoryAttrObj);
            //备注
            resultObj.Put("remark", remark);
            //入库单自定义字段
            resultObj.Put("inboundOrderCustomField", inboundOrderCustomField);
            //入库记录自定义字段
            resultObj.Put("recordCustomField", recordCustomField);
            return resultObj;
        }

        /// <summary>
        /// 添加操作结果
        /// </summary>
        private void AddOperateResult(DynamicObject dataEntity,Boolean status,string message)
        {
            // 增加操作结果
            var result = new OperateResult();
            result.SuccessStatus = status;
            result.Name = "推送入库数据";
            result.PKValue = dataEntity["Id"];
            result.Number = ObjectUtils.Object2String(this.BusinessInfo.GetBillNoField().DynamicProperty.GetValueFast(dataEntity));
            result.Message = message;
            this.OperationResult.OperateResult.Add(result);

        }
        /// <summary>
        /// 发送post请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        private string HttpPost(string url, string postData)
        {
            using (WebClient client = new WebClient())
            {
                client.Headers.Add("Content-Type", "application/json");
                //获取token
                string accessToken = getAccessToken();
                
                client.Headers.Add("X-AUTH", accessToken); // MES认证token， 这个看看自己需要嘛？

                byte[] postBytes = Encoding.UTF8.GetBytes(postData);
                byte[] responseBytes = client.UploadData(url, "POST", postBytes);
                string result = Encoding.UTF8.GetString(responseBytes);
                return result;
            }
        }
        /// <summary>
        /// 获取token
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        private string getAccessToken()
        {
            var sql = string.Format("select *  from BOT_t_BlackLakeParamter ");
            DataSet ds = DBServiceHelper.ExecuteDataSet(Context, sql);
            if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                //查询数据不为空
                DataRow  dataRow = ds.Tables[0].Rows[0];
                string accessToken = dataRow["FAccessToken"] != null ? dataRow["FAccessToken"].ToString() : "" ;
                string expireIn = dataRow["FExpireIn"] != null ? dataRow["FExpireIn"].ToString() : "";
                if (string.IsNullOrEmpty(accessToken))
                {
                    throw new KDException("401", "请到【黑湖MES集成参数配置】配置应用凭证信息并获取访问令牌！");
                }
                return accessToken;
            }
            else
            {
                throw new KDException("401", "请到【黑湖MES集成参数配置】配置应用凭证信息！");
            }
        }

        /// <summary>
        /// 更新token
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void updateAccessToken(DataRow dataRow)
        {
            string appKey = dataRow["FAppKey"] != null ? dataRow["FAppKey"].ToString() : "";
            string appSecret = dataRow["FAppSecret"] != null ? dataRow["FAppSecret"].ToString() : "";
            string tokenUrl = dataRow["FTokenUrl"] != null ? dataRow["FTokenUrl"].ToString() : "";
            if (string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(appSecret) || string.IsNullOrEmpty(tokenUrl))
            {
                throw new KDException("500", "【黑湖MES集成参数配置】的参数请配置完整！");
            }
            
        }


        /// <summary>
        /// 单位名称转换
        /// </summary>
        /// <param name="unitName"></param>
        /// <returns></returns>
        private string ConvertUnitName(string unitName)
        {
            if (string.IsNullOrEmpty(unitName))
            {
                return unitName;
            }
            if (string.Equals("克1", unitName))
            {
                return "克";
            }
            return unitName;
        }

        /// <summary>
        /// 保存日志
        /// </summary>
        /// <param name="fromId"></param>
        /// <param name="objectId"></param>
        /// <param name="objectNo"></param>
        /// <param name="apiUrl"></param>
        /// <param name="inputData"></param>
        /// <param name="returnData"></param>
        /// <param name="isSuccess"></param>
        /// <param name="errorMsg"></param>
        private void saveLog(string fromId, string objectId, string objectNo, string apiUrl, string inputData, string returnData, bool isSuccess, string errorMsg)
        {
            try
            {
                FormMetadata materialMetadata = MetaDataServiceHelper.Load(this.Context, "BOT_BlackLakeSyncLog") as FormMetadata;
                BusinessInfo businessInfo = materialMetadata.BusinessInfo;
                DynamicObjectType dynamicObjectType = businessInfo.GetDynamicObjectType();
                var unitDynamicObjectType = (businessInfo.GetField("FSyncFormId") as BaseDataField).RefFormDynamicObjectType;

                // 直接创建DynamicObject实例
                DynamicObject logEntity = new DynamicObject(dynamicObjectType);

                // 给DynamicObject添加属性并赋值（假设日志表有这些字段，实际需根据真实表结构修改）
                if (!string.IsNullOrEmpty(fromId))
                {
                    var unitObject = BusinessDataServiceHelper.LoadSingle(this.Context, fromId, unitDynamicObjectType);
                    if (unitObject != null)
                    {
                        logEntity["FSyncFormId"] = unitObject;
                    }
                }
                logEntity["FSyncObjectId"] = objectId;
                logEntity["FApiUrl"] = apiUrl;
                logEntity["FSyncDt"] = System.DateTime.Now;
                if (!string.IsNullOrEmpty(inputData) && inputData.Length > 1900)
                {
                    inputData = inputData.SubStr(0, 1900);
                }
                if (!string.IsNullOrEmpty(returnData) && returnData.Length > 1900)
                {
                    returnData = returnData.SubStr(0, 1900);
                }
                logEntity["FInputData"] = inputData;
                logEntity["FReturnData"] = returnData;
                logEntity["FIsSuccess"] = isSuccess;
                logEntity["FSyncObjectNo"] = objectNo;
                logEntity["FErrorMsg"] = errorMsg;

                //方法1：直接调用Orm保存，把数据保存到数据库
                BusinessDataServiceHelper.Save(this.Context, logEntity);
            }
            catch (Exception ex)
            {
                Logger.Error("500", ex.Message,ex);
            }
            
        }

    }
}
